import threading
import socket
import time

from concurrent.futures import ThreadPoolExecutor
import gevent

EOM = "\n"
#IOS objective-c swift
#安卓 java
#desktop app:java python go
#chrome ie firfox(HTTP,WebSocket)
class Server:
    def __init__(self):
        self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        # socket.socket(socket.AF_INET,socket.SOCK_DGRAM) UDP
        self.sockets = []
        self.lock = threading.Lock()
        # create thread pool executor
        self.e = ThreadPoolExecutor(max_workers=2)

    def start(self):
        self.socket.bind(("127.0.0.1",8888))
        self.socket.listen(20)
        # accept main thread
        t = threading.Thread(target=self.start_accept,args=())
        # t.setDaemon(True)
        t.start()

    def start_accept(self):
        while True:
            s,addr = self.socket.accept()
            self.lock.acquire()
            # put  client socket to socket list(循环发送)
            self.sockets.append(s)
            self.lock.release()
            # submit 提交,recv_send and submit is blocked.
            # self.e.submit(self.recv_send, s)
            # threading.Thread(target=self.recv_send,args=(s,)).start()
            job = gevent.spawn(self.recv_send, s)
            job.join()

    #recv message from client socket and send message to all socket.
    def recv_send(self,s: socket.socket):
        print("-")
        while True:
            content = ""
            while True:
                try:
                    gevent.sleep(0.001)
                    content += s.recv(1024).decode("utf-8")
                    gevent.sleep(0.001)
                except:
                    break
                if content == "" or content.endswith(EOM):
                    break
            if content == "":
                break
            #TODO do anything operation
            print(content)
            self.lock.acquire()
            for socket in self.sockets:
                socket.send(content.encode("utf-8"))
            self.lock.release()
        self.lock.acquire()
        if s in self.sockets:
            self.sockets.remove(s)
        self.lock.release()
        s.close()

    def end(self):
        self.lock.aquire()
        for socket in self.sockets:
            socket.close()
        self.lock.release()
        self.socket.close()
        self.e.shutdown()

if __name__ == "__main__":
    s = Server()
    s.start()
    time.sleep(1113)
    s.end()